package com.jwong.example.service.controller;

import com.jwong.example.service.model.Person;
import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@RestController
public class PersonController {
    private final List<String> people = Arrays.asList("mike", "suzy");
    private final MeterRegistry registry;

    public PersonController(MeterRegistry registry) {
        this.registry = registry;
    }

    @GetMapping("/api/people")
    // 用于查看请求时间的分布情况，分位数在0.5, 0.95, 0.999，
    // 50%的请求用时情况 5%的请求用时情况 0.1%请求用时情况
    @Timed(percentiles = {0.5, 0.95, 0.999}, histogram = true)
    public List<String> allPeople() {
        try {
            Thread.sleep(new Random().nextInt(500));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return people;
    }

    @GetMapping("/api/person/{id}")
    // Timed 的 value 属性值会构造以下指标：
    // person_requests_seconds_count Counter
    // person_requests_seconds_max   Gauge
    // person_requests_seconds_sum   Counter
    @Timed("person.requests")
    public Person person(@PathVariable String id) {
        return new Person(id, "jon-1", "schneider", "USA", "MO");
    }

    @GetMapping("/api/peopleAsync")
    public CompletableFuture<Collection<String>> personNamesAsync() {
        return CompletableFuture.supplyAsync(() -> Collections.singletonList("jon"));
    }


    @SuppressWarnings("unused")
    public List<String> fallbackPeople() {
        return Arrays.asList("old mike", "fallback frank");
    }

    @GetMapping("/api/fail")
    public String fail() {
        throw new RuntimeException("boom");
    }

    @GetMapping("/api/stats")
    public Map<String, Number> stats() {
        Timer t = registry.find("http.server.requests").tags("uri", "/api/people").timer();

        Map<String, Number> result = null;

        if (t != null) {
            result = new HashMap<>();

            result.put("count", t.count());
            result.put("max", t.max(TimeUnit.MILLISECONDS));
            result.put("mean", t.mean(TimeUnit.MILLISECONDS));
        }
        return result;


    }
}